package org.fing.edu.uy.esbadp.motor.strategies;

import java.util.LinkedList;
import java.util.List;
import java.util.logging.Level;

import org.fing.edu.uy.esbadp.core.AdpFlowInterface;
import org.fing.edu.uy.esbadp.core.AdpFlowLIST;
import org.fing.edu.uy.esbadp.core.AdpFlowUNI;
import org.fing.edu.uy.esbadp.core.entity.DMRegisteredService;
import org.fing.edu.uy.esbadp.core.entity.GenericTreeNode;
import org.fing.edu.uy.esbadp.core.entity.PropertiesMonitoring;
import org.fing.edu.uy.esbadp.core.interfaces.IAdpStrategy;
import org.fing.edu.uy.esbadp.logger.LoggerADP;


public class AdpStrategyEquivalentListService implements IAdpStrategy{

	private static final java.util.logging.Logger logger = LoggerADP.getLogger(AdpStrategyEquivalentListService.class.getSimpleName());

	/*
	 * 				  -> S_ToCanonical-> S1_FromCanonical -> equivalentVirtualService1 -> S1_ToCanonical -> S_FromCanonical -> 
	 * 			      -> ...
	 * FlowTree = LST -> S_ToCanonical-> Si_FromCanonical -> equivalentVirtualServicei -> Si_ToCanonical -> S_FromCanonical -> UNI
	 * 				  -> ...
	 * 				  -> S_ToCanonical-> SN_FromCanonical -> equivalentVirtualServiceN -> SN_ToCanonical -> S_FromCanonical ->
	 */
	@Override
	public GenericTreeNode<AdpFlowInterface> getAdpTree(DMRegisteredService service,List<DMRegisteredService> equivServices,PropertiesMonitoring properties) {
		try{	
			GenericTreeNode<AdpFlowInterface> treeNode = new GenericTreeNode<AdpFlowInterface>();	
			AdpFlowInterface list = new AdpFlowLIST();
			treeNode.setData(list);
			
			GenericTreeNode<AdpFlowInterface> uniNode = new GenericTreeNode<AdpFlowInterface>();
			AdpFlowInterface uni = new AdpFlowUNI();
			uniNode.setData(uni);
			
			for(DMRegisteredService equivalent: equivServices){
				AdpStrategyEquivalentService equivalentStrategy = new AdpStrategyEquivalentService(); 
				List<DMRegisteredService> equivalentList = new LinkedList<DMRegisteredService>();
				equivalentList.add(equivalent);
				GenericTreeNode<AdpFlowInterface> branch = equivalentStrategy.getAdpTree(service, equivalentList, properties);
		
				addLeaf(branch,uniNode);				
				treeNode.addChild(branch);
			}
			
			if (treeNode.getChildren().size() > 0){
				return treeNode;	
			}else{
				return null;
			}

		}catch(Exception ex){
			logger.log(Level.SEVERE, "Exception in AdpStrategyEquivalentListService...\n StackTarce => [ {0} ]", ex);	
			return null;
		}
	}
	
	private void addLeaf(GenericTreeNode<AdpFlowInterface> branch, GenericTreeNode<AdpFlowInterface> node) {
		GenericTreeNode<AdpFlowInterface>  iterBranch = branch;
		while(iterBranch.getChildren().size() > 0){
			iterBranch = iterBranch.getChildAt(0);
		}
		iterBranch.addChild(node);
	}
	
}
